﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Collections;

using Cards.Objects;
using Cards.Util;

namespace Cards.GUI
{
    class INS_BlackJackStage : INS_Stage
    {
        public INS_BlackJackStage(int _x, int _y, int _width, int _height, Form _parent, int _numOfPlayers)
        {
            sSide = 0;
            this.x = _x;
            this.y = _y;
            m_width = _width;
            m_height = _height;
            m_winParent = _parent;

            m_numOfPlayers = _numOfPlayers;
            m_insPackOfCards = new INS_PackOfCards(Constants.s_playerWidth / 2, Constants.s_playerHeight + Constants.s_alphay,
                                     global::Cards.Properties.Resources.bobai2, this,
                                     Constants.s_cardContainerWidth, Constants.s_cardContainerHeight);
            m_stage = new CBlackJackStage(this);
            m_insPlayer = new INS_BlackJackPlayer[m_numOfPlayers];

            int i = 0;
            for (i = 0; i < m_numOfPlayers / 2; i++)
            {
                m_insPlayer[i] = new INS_BlackJackPlayer((i % (m_numOfPlayers / 2)) * ((Constants.s_tableWidth) / (m_numOfPlayers / 2)),
                                                Constants.s_playerHeight * 2 - Constants.s_alphay * 2,
                                                i,
                                                "nguoichoi " + (i + 1),
                                                global::Cards.Properties.Resources.nguoichoi1,
                                                this,
                                                (i == 0) ? PLAYER_TYPE.HUMAN : PLAYER_TYPE.COMPUTER,
                                                ((Constants.s_tableWidth) / (m_numOfPlayers / 2)),
                                                Constants.s_playerHeight,
                                                0,
                                                0,
                                                Constants.BLACKJACK_NUMOFCARDS,
                                                Constants.BLACKJACK_MAX_NUMOFCARDS);
            }
            int id = i;
            for (i = (m_numOfPlayers / 2) + (m_numOfPlayers % 2) - 1; i >= 0; i--, id++)
            {
                m_insPlayer[id] = new INS_BlackJackPlayer(i * ((Constants.s_tableWidth) / ((m_numOfPlayers / 2) + (m_numOfPlayers%2))),
                                                Constants.s_alphay,
                                                id,
                                                "nguoichoi " + (id + 1),
                                                global::Cards.Properties.Resources.nguoichoi1,
                                                this,
                                                PLAYER_TYPE.COMPUTER,
                                                ((Constants.s_tableWidth) / ((m_numOfPlayers / 2) + (m_numOfPlayers % 2))),
                                                Constants.s_playerHeight,
                                                0,
                                                0,
                                                Constants.BLACKJACK_NUMOFCARDS,
                                                Constants.BLACKJACK_MAX_NUMOFCARDS);
            }

            ((INS_BlackJackPlayer)m_insPlayer[id - 1]).BANKER = true;

            Init();
        }

        public override void Init()
        {
            base.Init();

            sPlay = false;
            sBetMoney = 5000;

            m_numOfCards = Constants.BLACKJACK_NUMOFCARDS;
            m_maxNumOfCards = Constants.BLACKJACK_MAX_NUMOFCARDS;
        }

        public override void InitToContinuePlay()
        {
            base.InitToContinuePlay();

            for (int i = 0; i < m_numOfPlayers; i++)
            {
                ((INS_BlackJackPlayer)m_insPlayer[i]).InitCardsPosition();
                ((INS_BlackJackPlayer)m_insPlayer[i]).ResetCardsState();
                ((INS_BlackJackPlayer)m_insPlayer[i]).ResetPlayer();
            }

            sSide = 0;
            sBeginPlaying = true;
            sPlay = false;
            sBetMoney = 5000;
            m_insPackOfCards.ShowPicture();
        }


        public override void Step()
        {
            if (!sPlay || (m_insPlayer[sSide].PLAYERKIND == PLAYER_TYPE.COMPUTER))
            {
                return;
            }
            ((CBlackJackStage)m_stage).TakeCard();
        }

        public override void Skip()
        {
            if (!sPlay || m_insPlayer[sSide].PLAYERKIND == PLAYER_TYPE.COMPUTER)
            {
                return;
            }
            ((CBlackJackStage)m_stage).Skip();
        }


        public override void PlayNextStage()
        {
            sPlay = true;

            for (int i = 0; i < m_numOfPlayers; i++)
            {
                ((INS_BlackJackPlayer)m_insPlayer[i]).DeleteCardsArray();
                ((INS_BlackJackPlayer)m_insPlayer[i]).Init();
            }

            m_insPackOfCards.RemoveCards();
            m_insPackOfCards.MergeCards();

            m_insPackOfCards.DistributeBlackJackCards();
            //SortCards();
            CreateGUIToReplay();

            CardsDistributionEffect();
        }

        public override void BeginToPlay()
        {
            base.BeginToPlay();

            m_insPackOfCards.DistributeBlackJackCards();
            //SortCards();
            CreateGUI();

            CardsDistributionEffect();
        }

        public override void BeginNetworkPlaying()
        {
            base.BeginNetworkPlaying();

            if (MainFrame.s_isServer)
            {
                // Broadcast begin command
                String msg = IPC.PC.ToCommandMessageString();
                MainFrame.m_frmMultiGame.MULTIGAME.BeginGame(msg);
            }
            else
            {
                m_insPackOfCards.PC.CARDSARRAY = MainFrame.m_frmMultiGame.m_pcArrayCards;
                m_insPackOfCards.PC.INDEX = MainFrame.m_frmMultiGame.m_pcIndex;
            }

            m_insPackOfCards.DistributeBlackJackCards();
            //SortCards();
            CreateGUI();

            CardsDistributionEffect();
        }

        public override void PlayNetworkingNextStage()
        {
            sPlay = true;

            for (int i = 0; i < NUMPLAYERS; i++)
            {
                ((INS_BlackJackPlayer)m_insPlayer[i]).DeleteCardsArray();
                ((INS_BlackJackPlayer)m_insPlayer[i]).Init();
            }

            m_insPackOfCards.RemoveCards();
            m_insPackOfCards.MergeCards();

            if (MainFrame.s_isServer)
            {
                // Broadcast Continue command
                String msg = IPC.PC.ToCommandMessageString();
                MainFrame.m_frmMultiGame.MULTIGAME.ContinueGame(msg);
            }
            else
            {
                m_insPackOfCards.PC.CARDSARRAY = MainFrame.m_frmMultiGame.m_pcArrayCards;
                m_insPackOfCards.PC.INDEX = MainFrame.m_frmMultiGame.m_pcIndex;
            }

            m_insPackOfCards.DistributeBlackJackCards();
            //SortCards();

            CreateGUIToReplay();
            CardsDistributionEffect();
        }

        public override void CreateButton()
        {
            base.CreateButton();

            m_btnPlay = new Button();
            m_btnPlay.Text = "Rút thêm";
            m_btnPlay.Size = new Size(new Point(80, 22));
            m_btnPlay.Location = new Point(60, Constants.s_playerHeight * 2
                                            + Constants.s_cardContainerHeight + 21);
            m_btnPlay.BackColor = Color.DarkMagenta;
            m_btnPlay.ForeColor = Color.White;
            m_btnPlay.Click += new EventHandler(btnPlay_click);

            m_btnSkip = new Button();
            m_btnSkip.Text = "Đã xong";
            m_btnSkip.ForeColor = Color.White;
            m_btnSkip.Size = new Size(new Point(80, 22));
            m_btnSkip.Location = new Point(142, Constants.s_playerHeight * 2
                                            + Constants.s_cardContainerHeight + 21);
            m_btnSkip.BackColor = Color.DarkMagenta;
            m_btnSkip.Click += new EventHandler(btnSkip_click);

            this.Controls.Add(m_btnPlay);
            this.Controls.Add(m_btnSkip);
        }

        public override void CreateGUIToReplay()
        {
            for (int i = 0; i < m_numOfPlayers; i++)
            {
                ((INS_BlackJackPlayer)m_insPlayer[i]).CreateGUIToReplay();
            }
        }

        public override void CreatePlayerGUI()
        {
            for (int i = 0; i < m_numOfPlayers; i++)
            {
                ((INS_BlackJackPlayer)m_insPlayer[i]).CreateGUI();
                this.Controls.Add(m_insPlayer[i]);
            }
        }

        protected override void timer1_Tick(object sender, EventArgs e)
        {
            timerStartStage.Enabled = false;
            timerStartStage.Stop();
            
            m_insPlayer[sSide].ReceiveTurn();
        }

        public override void EndStage()
        {
            base.EndStage();

            CalculateMoney();

            for (int i = 0; i < m_numOfPlayers; i++)
            {
                //if (m_insPlayer[i].PLAYERKIND == PLAYER_TYPE.COMPUTER)
                {
                    m_insPlayer[i].DisplayCards();
                }
                m_insPlayer[i].AddMoney();
            }

            m_insPackOfCards.HidePicture();
        }

        public void CalculateMoney()
        {
            INS_BlackJackPlayer banker = GetBanker();
            int bankerScore = CheckRule_BlackJack.EvaluateScore(banker);

            for (int i = 0; i < m_numOfPlayers; i++)
            {
                INS_BlackJackPlayer player = (INS_BlackJackPlayer)m_insPlayer[i];
                if (!player.BANKER)
                {
                    BLACKJACK_RANK playerRank = CheckRule_BlackJack.GetRank(player);
                    BLACKJACK_RANK bankerRank = CheckRule_BlackJack.GetRank(banker);

                    if (playerRank < bankerRank)
                    {
                        player.CalculateMoney(sBetMoney);
                        banker.CalculateMoney(-sBetMoney);
                    }
                    else if (playerRank > bankerRank)
                    {
                        player.CalculateMoney(-sBetMoney);
                        banker.CalculateMoney(sBetMoney);
                    }
                    else if (playerRank == bankerRank)
                    {
                        if (bankerRank == BLACKJACK_RANK.R_AVERAGE)
                        {
                            if (CheckRule_BlackJack.EvaluateScore(player) > CheckRule_BlackJack.EvaluateScore(banker))
                            {
                                player.CalculateMoney(sBetMoney);
                                banker.CalculateMoney(-sBetMoney);
                            }
                            else if (CheckRule_BlackJack.EvaluateScore(player) < CheckRule_BlackJack.EvaluateScore(banker))
                            {
                                player.CalculateMoney(-sBetMoney);
                                banker.CalculateMoney(sBetMoney);
                            }
                        }
                    }
                }
            }
        }

        public INS_BlackJackPlayer GetBanker()
        {
            for (int i = 0; i < m_numOfPlayers; i++)
            {
                if (((INS_BlackJackPlayer)m_insPlayer[i]).BANKER)
                {
                    return (INS_BlackJackPlayer)m_insPlayer[i];
                }
            }
            return null;
        }
    }
}
